﻿using System;
using System.Web;
using System.Web.Compilation;
using System.Web.UI;

using BlueCMS.Core.Entities;
using BlueCMS.Core.Services;
using BlueCMS.Core.IoC;
using BlueCMS.Core.Data;
using BlueCMS.Core.Data.Query;

namespace BlueCMS.Core
{
    public class CmsDispatch : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            string url = CmsApplication.CmsOriginalUrl ?? "/index.cms";
            string domain = context.Request.Url.Host.ToLower();
            if (domain.StartsWith("www."))
            {
                domain = domain.Remove(0, 4);
            }

            Website website = WebsiteService.GetWebsiteForDomain(domain);
            if (website == null)
            {
                throw new HttpException("No website configured for this domain");
            }

            // Find the node for this request
            Node node = NodeService.GetNodeForWebsiteAndPath(website, url);
            if (node == null)
            {
                throw new HttpException(404, "Page not found");
            }

            // Find the user for this request. If we aren't authenticated then use the guest user
            User user = null;
            if (context.User != null && context.User.Identity.IsAuthenticated)
            {
                user = UserService.GetUserForWebsiteByName(website, context.User.Identity.Name);
            }
            else
            {
                user = UserService.GetGuestUserForWebsite(website);
            }
            CmsApplication.CmsUser = user;

            // Verify that the user has permissions for this node
            if(!UserService.UserHasPermissionForNode(user, "NODE", "VIEW", node))
            {
                if (user.isguest)
                {
                    context.Response.Redirect("/login.cms?return_url=" + context.Server.UrlEncode(CmsApplication.CmsOriginalUrl));
                }
                else
                {
                    context.Response.Redirect("/access_denied.cms");
                }
                return;
            }

            // Let the node handler handle the request
            NodeType nodeType = NodeService.GetNodeTypeForNode(node);
            string handlerPath = String.Format("~/_System/handlers/{0}", nodeType.Handler);
            Type handlerType = BuildManager.GetCompiledType(handlerPath);
            if (handlerType == null)
            {
                throw new HttpException("No handler configured for this path");
            }

            IHttpHandler handler = Activator.CreateInstance(handlerType) as IHttpHandler;
            if (handler == null)
            {
                throw new HttpException("No handler configured for this path");
            }

            CmsApplication.CmsNode = node;
            CmsApplication.CmsWebsite = website;

            handler.ProcessRequest(context);
        }

        public bool IsReusable
        {
            get { return false; }
        }
    }
}
